package com.chushouya.product.service.admin.impl;

import com.general.framework.core.lang.*;
import com.chushouya.common.support.Contexts;
import com.general.framework.core.enums.StatusEnum;
import com.general.framework.core.schema.PageResult;
import com.chushouya.product.dao.entity.BrandEntity;
import com.chushouya.product.dao.entity.CategoryBrandEntity;
import com.chushouya.product.dao.repository.BrandRepository;
import com.chushouya.product.dao.repository.CategoryBrandRepository;
import com.chushouya.product.dto.admin.brand.BrandQuery;
import com.chushouya.product.dto.admin.category.CategoryBindBrandDTO;
import com.chushouya.product.dto.admin.category.CategoryBrandListDTO;
import com.chushouya.product.dto.admin.category.CategoryBrandQuery;
import com.chushouya.product.dto.admin.category.CategoryToBindQuery;
import com.chushouya.product.service.admin.CategoryBrandService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

@Service
@Slf4j
public class CategoryBrandServiceImpl implements CategoryBrandService {

    @Resource
    private CategoryBrandRepository categoryBrandRepository;

    @Resource
    private BrandRepository brandRepository;

    @Override
    public Long bind(Long categoryId, Long brandId) {
        CategoryBrandQuery query = new CategoryBrandQuery();
        query.setCategoryId(categoryId);
        query.setBrandId(brandId);
        CategoryBrandEntity exist = categoryBrandRepository.selectOne(query);
        Check.isNull(exist, "品牌已经绑定到当前商品分类，不能重复绑定");
        CategoryBrandEntity entity = new CategoryBrandEntity();
        entity.setCategoryId(categoryId);
        entity.setBrandId(brandId);
        entity.setSort(categoryBrandRepository.getMaxSort(categoryId) + 1);
        entity.setCreateTime(Dates.getTimeNow());
        entity.setHandleUser(Contexts.getUserContext().getUserName());
        categoryBrandRepository.insertSelective(entity);
        return entity.getCategoryBrandId();
    }

    @Override
    public void cancelBind(Long categoryBrandId) {
        Check.notNull(categoryBrandId, "categoryBrandId can not be null");
        categoryBrandRepository.deleteByPrimaryKey(categoryBrandId);
    }

    @Override
    public PageResult<CategoryBindBrandDTO> selectCategoryToBindBrands(CategoryToBindQuery query) {
        CategoryBrandQuery brandIdQuery = new CategoryBrandQuery();
        brandIdQuery.setCategoryId(query.getCategoryId());
        List<CategoryBrandEntity> categoryBrandList = categoryBrandRepository.selectList(brandIdQuery);
        BrandQuery brandQuery = new BrandQuery();
        brandQuery.setPage(query.getPage());
        brandQuery.setSize(query.getSize());
        brandQuery.setBrandName(query.getKeyword());
        brandQuery.setStatus(StatusEnum.normal.value());
        brandQuery.setDelFlag(Numbers.INTEGER_ZERO);
        final PageResult<BrandEntity> brandPageResult = brandRepository.selectPageResult(brandQuery);
        List<CategoryBindBrandDTO> pageList = Lists.newArrayList();
        brandPageResult.getRows().forEach(brand -> {
            CategoryBindBrandDTO dto = Beans.copy(brand, CategoryBindBrandDTO.class);
            final CategoryBrandEntity bind = categoryBrandList.stream().filter(v -> v.getBrandId().equals(brand.getBrandId())).findFirst().orElse(null);
            if (Objects.nonNull(bind)) {
                dto.setCategoryBrandId(bind.getCategoryBrandId());
                dto.setIsBind(Boolean.TRUE);
            }
            pageList.add(dto);
        });
        return new PageResult<>(pageList, brandPageResult.getTotal());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long editSort(Long bindId, Integer sort) {
        CategoryBrandEntity update = new CategoryBrandEntity();
        update.setCategoryBrandId(bindId);
        update.setSort(sort);
        categoryBrandRepository.updateByPrimaryKeySelective(update);
        return bindId;
    }

    @Override
    public List<CategoryBrandListDTO> listCategoryBrand(Long categoryId, String brandName) {
        CategoryBrandQuery query = new CategoryBrandQuery();
        query.setCategoryId(categoryId);
        List<CategoryBrandEntity> categoryBrandEntities = categoryBrandRepository.selectList(query);
        final List<BrandEntity> brandEntityList = brandRepository.selectAll();
        if (Lists.isEmpty(categoryBrandEntities)) {
            return Lists.emptyList();
        }
        List<CategoryBrandListDTO> categoryBrandList = Lists.newArrayList();
        categoryBrandEntities.forEach(categoryBrandEntity -> {
            CategoryBrandListDTO categoryBrand = new CategoryBrandListDTO();
            BrandEntity brandEntity = brandEntityList.stream()
                    .filter(brand -> brand.getBrandId().equals(categoryBrandEntity.getBrandId()))
                    .findFirst()
                    .orElse(null);
            if (Objects.nonNull(brandEntity) && Objects.equals(StatusEnum.normal.value(), brandEntity.getStatus())) {
                categoryBrand.setBrandId(categoryBrandEntity.getBrandId());
                categoryBrand.setBindId(categoryBrandEntity.getCategoryBrandId());
                categoryBrand.setBrandName(brandEntity.getBrandName());
                categoryBrand.setBrandImage(brandEntity.getBrandImage());
                categoryBrand.setSort(categoryBrandEntity.getSort());
                categoryBrandList.add(categoryBrand);
            }
        });
        return categoryBrandList;
    }

    @Override
    public Boolean hasCategoryBindBrand(Long brandId) {
        CategoryBrandQuery query = new CategoryBrandQuery();
        query.setBrandId(brandId);
        return categoryBrandRepository.selectCount(query) > Numbers.INTEGER_ZERO;
    }

    @Override
    public Boolean hasBrandBindCategory(Long categoryId) {
        CategoryBrandQuery query = new CategoryBrandQuery();
        query.setCategoryId(categoryId);
        return categoryBrandRepository.selectCount(query) > Numbers.INTEGER_ZERO;
    }




}
